//! \file CoreThread.cpp
//! \brief TODO: Document
// -----------------------------------------------------------------------------
//! This program is free software; you can redistribute it and/or
//! modify it under the terms of the GNU General Public License
//! as published by the Free Software Foundation; either version 2
//! of the License, or (at your option) any later version.
//!
//! This program is distributed in the hope that it will be useful,
//! but WITHOUT ANY WARRANTY; without even the implied warranty of
//! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//! GNU General Public License for more details.
//!
//! You should have received a copy of the GNU General Public License
//! along with this program; if not, write to the Free Software Foundation,
//! Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// -----------------------------------------------------------------------------
#include "CoreThread.h"
#include <pthread.h>
#include <vector>

namespace Core {


// =====[ Local Variables ]=====================================================
static std::vector<tTHREAD*> ThreadArray;

// =====[ Local Implementation ]================================================


// =============================================================================
// Implement: ThreadCreate
// -----------------------------------------------------------------------------
tERROR ThreadCreate(tTHREAD *pThread, tTHREAD_RUN_FX pRunFx, void *Args)
{
  // Validate our arguments.
  // TODO: complete ???

  // TODO: create thread memory here, then only pass in the RunFx with the ARGS.  Using JoinAll the
  // thread stuff can be completely self contained.

  // Create the thread
  if (pthread_create(pThread, NULL, pRunFx, Args) != 0)
    { return (dERROR_CORE_UNABLE_TO_CREATE_THREAD); }

  // Append the newly created thread to the thread array.
  ThreadArray.push_back(pThread);

  // Finally, return success.
  return (dNO_ERROR);
}


// =============================================================================
// Implement: ThreadSelf
// -----------------------------------------------------------------------------
tTHREAD ThreadSelf(void)
{
  // TODO; finish implementation
  //pthread_t pthread_self(void);
  return ((tTHREAD)(pthread_self()));
}


// =============================================================================
// Implement: ThreadJoin
// -----------------------------------------------------------------------------
tERROR ThreadJoin(tTHREAD Thread, void **pExitValue)
{
  // Validate our arguments.
  // TODO: complete

  // Create the thread
  if (pthread_join(Thread, pExitValue) != 0)
    { return (dERROR_CORE_UNABLE_TO_JOIN_THREAD); }
  return (dNO_ERROR); // Otherwise, return success.
}


// =============================================================================
// Implement: ThreadExit
// -----------------------------------------------------------------------------
void ThreadExit(void *pValue)
{
  pthread_exit(pValue);
}


// =============================================================================
// Implement: ThreadKill
// -----------------------------------------------------------------------------
int ThreadKill(tTHREAD Thread, int Signal)
{
  // TODO: implement
  return (0);
}


// =============================================================================
// Implement: ThreadJoinAll
// -----------------------------------------------------------------------------
void ThreadJoinAll(void)
{
  size_t Index;

  // Iterate through each thread and join it.
  for (Index = 0; Index < ThreadArray.size(); Index++)
  {
    ThreadJoin((tTHREAD)ThreadArray[Index], NULL);
  }

//    std::vector<tTHREAD*>::const_iterator Thread;
//    for(Thread=ThreadArray.begin(); Thread!=ThreadArray.end(); Thread++)
//    {
//      ThreadJoin(*Thread, NULL);
//  //    cout << *cii << endl;
//    }
}


} // namespace Core
